package com.vonchenchen.simplechartframe.dashboardview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;

/**
 * Created by vonchenchen on 2016/2/2 0002.
 */
public class DashboardView extends AbsboardView{

    Context mCtx;

    private final int POINTER_CENTER_RADIUS = 20;
    private final int POINTER_LENGHT_SIZE = 80;
    private final int POINTER_STROCKE_WIDTH = 3;

    private final int BOARD_STOKE_SIZE = 10;

    //set pointer center's position in the view
    private final double CENTER_POSITION_X = 0.5;
    private final double CENTER_POSITION_Y = 0.5;

    //set range of view refrence normal location
    private final double RADIUS_TOTLE = 220;
    private final double RADIUS_ZERO = 180;

    private final int TEXT_SIZE_MAIN = 50;

    private int mPointerCenterRadius;
    private int mPointerLengthSize;
    private int mPointerStrokeWidth;
    private int mBoardStrokeWidth;

    private Paint mBoardPaintColor;
    private Paint mBoardPaintCover;
    private Shader mBoardShader;

    private Paint mPointerPaint;
    private Paint mTextPaint;

    private float mPinterCenterRadius;
    private float mPointerLength;

    private int mMesuredHeight;
    private int mMesuredWidth;

    //set default max value
    private double mMaxValue = 100;
    //set current value
    private double mCurrValue = 0;

    private RectF mBoardOval;
    private float mCenterY;
    private float mCenterX;

    private float mTextX;
    private float mTextY;

    private int mMainTextSize;

    public DashboardView(Context context) {
        super(context);
        this.mCtx = context;
        initSize();
        initPaint();
    }

    public DashboardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mCtx = context;
        initSize();
        initPaint();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        mMesuredHeight = MeasureSpec.getSize(heightMeasureSpec);
        mMesuredWidth = MeasureSpec.getSize(widthMeasureSpec);

        //CENTER_POSITION_Y
        mBoardOval = new RectF(mBoardStrokeWidth, mBoardStrokeWidth, mMesuredHeight-mBoardStrokeWidth, mMesuredHeight-mBoardStrokeWidth);
        mCenterY = (float)(mMesuredHeight * CENTER_POSITION_Y);
        mCenterX = (float)(mMesuredWidth * CENTER_POSITION_X);

        mBoardShader = new LinearGradient(0, 0, (float)(mMesuredWidth*0.8), 0,
                new int[] {Color.GREEN, Color.YELLOW,
                        Color.RED }, null, Shader.TileMode.CLAMP);
        mBoardPaintColor.setShader(mBoardShader);

        mTextX = (float) (mMesuredWidth * 0.1);
        mTextY = (float) (mMesuredHeight * 0.9);
    }

    private void initSize(){
        mPointerCenterRadius = dip2px(POINTER_CENTER_RADIUS);
        mPointerLengthSize = dip2px(POINTER_LENGHT_SIZE);
        mPointerStrokeWidth = dip2px(POINTER_STROCKE_WIDTH);
        mBoardStrokeWidth = dip2px(BOARD_STOKE_SIZE);
        mMainTextSize = dip2px(TEXT_SIZE_MAIN);
    }

    private void initPaint(){
        mBoardPaintColor = new Paint();
        mBoardPaintColor.setStyle(Paint.Style.STROKE);
        mBoardPaintColor.setStrokeWidth(mBoardStrokeWidth);
        mBoardPaintColor.setColor(0x880000FF);

        mBoardPaintCover = new Paint();
        mBoardPaintColor.setAntiAlias(true);
        mBoardPaintCover.setColor(0xffffffff);

        mPointerPaint = new Paint();
        mPointerPaint.setAntiAlias(true);
        mPointerPaint.setColor(0xffff0000);
        mPointerPaint.setStrokeWidth(mPointerStrokeWidth);

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(0xffff0000);
        mTextPaint.setTextSize(mMainTextSize);
    }

    //data is a value which unit is degree
    private void drawPointer(double degreeData, Canvas canvas){

        mPinterCenterRadius = POINTER_CENTER_RADIUS;

        canvas.drawCircle(mCenterX, mCenterY, mPinterCenterRadius, mPointerPaint);

        double arc = 3.1415*degreeData/180;
        double endX = mCenterX + mPointerLengthSize * Math.cos(arc);
        double endY = mCenterY - mPointerLengthSize * Math.sin(arc);
        canvas.drawLine(mCenterX, mCenterY, (float) endX, (float) endY, mPointerPaint);
    }

    private void drawPointerDeviation(double degreeData, Canvas canvas){

        if(degreeData > RADIUS_TOTLE){
            degreeData = RADIUS_TOTLE;
        }else if(degreeData < 0){
            degreeData = 0;
        }

        double absDegreeArc = RADIUS_TOTLE - degreeData;
        //set start position
        absDegreeArc = absDegreeArc - (RADIUS_TOTLE - 180);
        drawPointer(absDegreeArc, canvas);
    }

    private void drawBoard(Canvas canvas){
        canvas.drawArc(mBoardOval, 180, 220, false, mBoardPaintColor);
    }

    private void drawText(Canvas canvas){
        canvas.drawText(mCurrValue+"", mTextX, mTextY, mTextPaint);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //drawPointer(90, canvas);

        double drgree = RADIUS_TOTLE * mCurrValue/mMaxValue;
        drawPointerDeviation(drgree, canvas);
        drawBoard(canvas);
        drawText(canvas);
    }

    public int dip2px(float dipValue) {
        float scale = this.mCtx.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    public double getMaxValue() {
        return mMaxValue;
    }

    public void setMaxValue(int maxValue){
        this.mMaxValue = maxValue;
    }

    public double getCurrValue(){
        return mCurrValue;
    }

    public void setCurrValue(int currValue){
        this.mCurrValue = currValue;
        invalidate();
    }
}
